package van.planifolia.demo01;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * Created by Intellij IDEA<br>
 * 反射操作方法
 * @author Planifolia.Van
 * @version 1.0
 * @date 2022/10/27 17:04
 */
public class ReflexOperationMethods {

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        getMethods();
        operationMethods();
    }

    public static void getMethods() throws NoSuchMethodException{
        // 分别获取他们的实例对象与反射对象
        Animal animal = new Animal();
        Neko neko = new Neko();
        Class<? extends Animal> animalClass = animal.getClass();
        Class<? extends Neko> nekoClass = neko.getClass();

        // 使用getMethod可以获取指定的自己类或者父类中的public方法，指定条件为方法的参数列表+方法名字
        System.out.println("Animal类中的show方法");
        System.out.println(animalClass.getMethod("show"));
        // 使用getMethods可以获取自己类以及父类中全部的public方法
        System.out.println("Neko类以及父类中的所有public方法");
        Arrays.stream(nekoClass.getMethods()).forEach(System.out::println);

        // 使用getDeclaredMethod可以获取指定自己类中的任意方法包括私有方法。指定条件为方法的参数列表+方法名字
        System.out.println("Animal类中的私有方法getShow");
        System.out.println(animalClass.getDeclaredMethod("getShow", String.class));
        // 使用getDeclaredMethods可以获取自己类中的所有方法包括私有方法
        System.out.println("Neko自己类中的所有方法，包括private方法");
        Arrays.stream(nekoClass.getDeclaredMethods()).forEach(System.out::println);
    }

    public static void operationMethods() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 分别获取他们的实例对象与反射对象
        Animal animal = new Animal();
        Neko neko = new Neko();
        Class<? extends Animal> animalClass = animal.getClass();
        Class<? extends Neko> nekoClass = neko.getClass();

        // 获取一个Animal中的show（无返回值无参数方法）方法并且执行
        Method show = animalClass.getMethod("show");
        show.invoke(animal);
        // 获取一个Animal中的私有方法getShow（有参数有返回值的方法） 方法并且执行
        Method getShow = animalClass.getDeclaredMethod("getShow", String.class);
        // 开启私有的访问权限
        getShow.setAccessible(true);
        Object result = getShow.invoke(animal, "长颈鹿");
        System.out.println(result);


    }
}
class Animal{
    public void show(){
        System.out.println("动物类");
    }
    private String getShow(String name){
        System.out.println("动物类"+name);
        return "动物类";
    }
}
class Neko{
    public void run(){
        System.out.println("小猫跑");
    }
    private String getName(String name){
        System.out.println("我是小猫" + name);
        return "我是小猫"+name;
    }
}

